package com.s2sh.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.hibernate.metadata.ClassMetadata;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.s2sh.dao.BaseDao;

/**
 * 泛型概念：
 * 		泛型是一种类型
 * Type  代表java语言中所有的类型
 * ParameterizedType是Type类型中的一种，代表泛型，即此处的BaseDaoImpl<T>的类型为ParameterizedType类型
 * 泛型ParameterizedType接口中定义了三个方法：
 * 		Type[] getActualTypeArguments() 返回<T>泛型参数数组
 * 		Type getRawType() 返回BaseDaoImpl<T>泛型类实现的接口BaseDao
 * 		Type getOwnerType() 返回泛型BaseDaoImpl<T>
 * @author LC
 */
public class BaseDaoImpl<T> implements BaseDao<T>{
	
	@Resource(name="hibernateTemplate")
	private HibernateTemplate hibernateTemplate ;
	
	private Class entity ;
	private ClassMetadata metadata ;
	/**
	 * 在构造器中得到T的类型
	 */
	public BaseDaoImpl() {
		/**
		 * this：代表子类的对象
		 *  	this.getClass().getGenericSuperclass() ：得到泛型父类ParameterizedType pt =  BaseDaoImpl<T>
		 * 		如果对泛型类BaseDaoImpl<T>进行实例化，并且不传递泛型参数T的话，那么BaseDaoImpl创建的实例为Class类型，而不是上边得到的ParameterizedType类型
		 * 		这样的话，使用this.getClass().getGenericSuperclass()时将会出现错误：
		 * 			Caused by : java.lang.ClassCastException : java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
		 * 		结论：
		 * 			不能直接对BaseDaoImpl进行无参<T>实例化
		 * 获取泛类的参数T：
		 * 		T的实际类型Class entity = (Class)pt.getActualTypeArguments()[0] ;
		 */
		ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass() ;
		entity = (Class) pt.getActualTypeArguments()[0] ;
	}
	
/*	@PostConstruct
	public void init() {
		this.metadata = this.hibernateTemplate.getSessionFactory().getClassMetadata(entity) ;
	}*/

	public List<T> getAllEntry() {
		return this.hibernateTemplate.find("from " + entity.getSimpleName()) ;
	}

	public T getEntryById(Serializable id) {
		return (T) this.hibernateTemplate.get(entity, id) ;
	}

	public void saveEntry(T t) {
		this.hibernateTemplate.save(t) ;
	}

	public void updateEntry(T t) {
		this.hibernateTemplate.update(t) ;
	}

	public void deleteEntry(Serializable id) {
		Object object = this.hibernateTemplate.get(entity, id) ;
		this.hibernateTemplate.delete(object) ;
	}

	public Collection<T> getEntriesByIds(Serializable... ids) {
		List<Object> entities = null ;
		if(ids != null && ids.length > 0) {
			entities = new ArrayList<Object>() ;
			for (Serializable id : ids) {
				Object object = this.hibernateTemplate.get(entity, id) ;
				entities.add(object) ;
			}
		}
		return (Collection<T>) entities;
	}

/*	public Set<T> getEntryByIds(Serializable [] ids) {
		Set<Object> entities = null ;
		if(ids != null && ids.length > 0) {
			entities = new HashSet<Object>() ;
			StringBuffer buffer = new StringBuffer() ;
			buffer.append("from " + entity.getSimpleName()) ;
			buffer.append(" where " + metadata.getIdentifierPropertyName() + " in(") ;
			for (int i = 0; i < ids.length; i++) {
				if(i == ids.length-1) {
					buffer.append(ids[i]) ;
				} else {
					buffer.append(ids[i] + ",") ;
				}
			}
			buffer.append(")") ;
			entities = (Set<Object>) this.hibernateTemplate.find(buffer.toString());
		}
		return (Set<T>) entities ;
	}
	*/
	

}
